/*
    通用功能类，与业务无关的功能实现
        1. 获取系统时间
        2. 获取文件大小
        3. 创建目录
        4. 获取文件所在目录
*/
#ifndef __M_UTIL_H__
#define __M_UTIL_H__

#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <ctime>
#include <cassert>
#include <sys/stat.h>

namespace zdflog
{
    namespace util
    {
        /**
         * @brief 日期和时间相关工具类
         *
         * 提供获取系统时间戳等与时间相关的静态方法
         */
        class date
        {
        public:
            /**
             * @brief 获取当前系统时间戳
             * @return 自纪元以来的秒数（size_t类型）
             */
            static size_t now() { return (size_t)time(nullptr); }
        };

        /**
         * @brief 文件和路径操作工具类
         *
         * 提供文件检查、路径解析、目录创建等静态方法
         */
        class file
        {
        public:
            /**
             * @brief 检查文件或目录是否存在
             * @param name 要检查的文件或目录路径
             * @return 如果存在返回true，否则返回false
             */
            static bool exists(const std::string &name)
            {
                struct stat st;
                return stat(name.c_str(), &st) == 0;
            }

            /**
             * @brief 获取文件所在的目录路径
             * @param name 文件路径
             * @return 文件所在目录路径，如果未找到目录分隔符则返回"."
             */
            static std::string path(const std::string &name)
            {
                if (name.empty())
                    return ".";
                size_t pos = name.find_last_of("/\\");
                if (pos == std::string::npos)
                    return ".";
                return name.substr(0, pos + 1);
            }

            /**
             * @brief 递归创建目录
             *
             * 逐级检查并创建目录，支持绝对路径和相对路径
             *
             * @param path 要创建的目录路径
             */
            static void create_directory(const std::string &path)
            {
                if (path.empty())
                    return;
                if (exists(path))
                    return;

                size_t pos, idx = 0;
                while (idx < path.size())
                {
                    // 查找下一个路径分隔符
                    pos = path.find_first_of("/\\", idx);

                    if (pos == std::string::npos)
                    {
                        // 处理最后一级目录
                        mkdir(path.c_str(), 0755);
                        return;
                    }

                    if (pos == idx)
                    {
                        // 处理路径开头的斜杠或连续斜杠
                        idx = pos + 1;
                        continue;
                    }

                    // 提取当前子目录
                    std::string subdir = path.substr(0, pos);

                    // 跳过特殊目录
                    if (subdir == "." || subdir == "..")
                    {
                        idx = pos + 1;
                        continue;
                    }

                    // 如果子目录不存在则创建
                    if (!exists(subdir))
                    {
                        mkdir(subdir.c_str(), 0755);
                    }

                    idx = pos + 1;
                }
            }
        };
    }
}
#endif